import { EnumChatMsgExecutedState, EnumChatMessageType, EnumChatState, EnumSender, EnumMyChatCardAction, EnumMyChatCardIcon, MyChatMsgResult } from "@/apis/endpoint/model";
import GpContainer from "@/components/GpContainer";
import GpFontIcon from "@/components/GpFontIcon";
import GpNavbar from "@/components/GpNavbar";
import { GpTouchableView } from "@/components/GpTouchableView";
import GpVerticelLine from "@/components/GpVerticelLine";
import { NAVIGATION_BASE_LAYOUT } from "@/hooks/useLayout";
import { SafeArea } from "@taroify/core";
import { Image, Input, ScrollView, Text, View } from "@tarojs/components";
import { useRouter } from "@tarojs/taro";
import clsx from "clsx";
import React, { useState } from "react";
import { useActions } from "./composables/useActions";
import { useChatDetail } from "./composables/useChatDetial";
import { useMessages } from "./composables/useMessages";
import styles from "./index.module.css";
import { type RouteParams } from "./types";
import { navigate } from "@/utils/navigation";
import { pageMapper } from "@/constants/pageMap";
import { isSetValue } from "@/utils/helper";

export default function Index() {
  const positionStateMap = new Map<EnumChatState, string>([
    [EnumChatState.不合适, "不合适"],
    [EnumChatState.匹配成功, "匹配成功"],
    [EnumChatState.已约面, "已约面"],
    [EnumChatState.待介入, "待介入"]
  ])
  const [navigationHeight, setNavigationHeight] = useState(NAVIGATION_BASE_LAYOUT.navigationHeight + NAVIGATION_BASE_LAYOUT.statusBarHeight)
  const params = useRouter<RouteParams>().params
  const {
    isRequestCardType,
    isSpecialMessage,
    fetchMessageList,
    handleSend,
    input,
    messages,
    onScrollToUpper,
    scrollIntoView,
    setInput,
    handleSocketMessage,
    handleRequestCard,
    handleCopyText,
    handleCallphone,
    getNextMessage,
    previewResume,
    handleInterviewInvite
  } = useMessages(params)
  const {
    actionOptions,
    handleAction,
    renderConfirmPopup
  } = useActions(params, getNextMessage)
  const {
    chatDetail,
  } = useChatDetail(params, {
    open: () => fetchMessageList(true),
    message: handleSocketMessage,
  })
  function renderChat() {
    return (
      <View className="flex-1 h-0 py-[24px] box-border">
        <ScrollView
          scrollY
          style={{ height: "100%" }}
          onScrollToUpper={onScrollToUpper}
          scrollIntoView={scrollIntoView}
        >
          {renderJobCard()}
          {renderTime()}
          {
            messages.map(renderMessage)
          }
        </ScrollView>
      </View>
    )
  }
  function renderJobCard() {
    return (
      <View className="px-[32px] mb-[56px]">
        <View className="h-[208px] rounded-[24px] shadow-[0_0_32px_rgba(46,41,77,0.04)] px-[28px] bg-white flex flex-col justify-center"
          style={{backgroundImage: "radial-gradient(60.72% 98.69% at 98.69% 0%, #E5EDFF 0%, #ffffff00 100%);"}}
        >
          <View className="flex flex-row justify-between gap-[44px] box-border">
            <Text className="text-[32px] leading-[36px] font-bold text-primary">{chatDetail?.jobName}</Text>
            {
              chatDetail?.memberState
              ? (
              <View className="text-theme gap-[8px] flex flex-row items-center h-[48px] rounded-[24px] bg-theme/10 px-[16px]">
                <GpFontIcon name="icon-xiaozhibiaotizhuangshi" size={24} className="text-inherit" />
                <Text className="text-[24px] leading-[24px] font-medium">
                  {positionStateMap.get(chatDetail?.memberState)}
                </Text>
              </View>
              ) : null
            }
          </View>
          <View className="text-secondary text-[28px] leading-[28px] flex flex-row gap-[16px] items-center mt-[10px]">
            <Text>{chatDetail?.companyName}</Text>
            <GpVerticelLine height={16} width={2} color="#ACAEB2" />
            <Text>{chatDetail?.industryName ?? '--'}</Text>
            <GpVerticelLine height={16} width={2} color="#ACAEB2" />
            <Text className="text-theme">{chatDetail?.jobSalaryDisplay}</Text>
          </View>
          <View className="text-third text-[24px] leading-[24px] whitespace-nowrap mt-[24px]">
            <Text className="text-theme font-medium">匹配度 {chatDetail?.matchScore}%</Text>
            <Text className="pl-[8px]">
              · {chatDetail?.matchResult}
            </Text>
          </View>
        </View>
      </View>
    )
  }
  function renderMessage(message: MyChatMsgResult) {
    let node: INullable<React.ReactNode> = null
    if (message.type === EnumChatMessageType.文本) {
      node = renderTextContent(message)
    } else if (isRequestCardType(message)) {
      node = renderRequestCard(message)
    } else if (isSpecialMessage(message)) {
      // TODO: 待定
    } else if (message.type === EnumChatMessageType.求职者发简历) {
      node = [
        <View className={styles.message}>{renderTipMessage(message)}</View>,
        renderResumePreviewCard(message)
      ]
    } else if ([EnumChatMessageType.HR同意换手机, EnumChatMessageType.HR同意换微信].includes(message.type)) {
      node = renderReplyCard(message)
    } else if ([EnumChatMessageType.HR约面试].includes(message.type)) {
      node = renderInterviewInvite(message)
    } else if ([EnumChatMessageType.求职者同意面试邀请, EnumChatMessageType.求职者拒绝面试邀请].includes(message.type)) {
      node = renderInterviewInviteTip(message)
    } else if (message.content) {
      node = renderTipMessage(message)
    }
    if (node) {
      return <View key={message.id} className={styles.message} id={`scroll_into_view_${message.id}`}>{node}</View>
    }
    return null
  }
  function renderTime() {
    return (
      <View className={styles.message}>
        <View className="text-center text-placeholder text-[24px] !leading-[24px]">
          09:56
        </View>
      </View>
    )
  }
  function renderTextContent(message: MyChatMsgResult) {
    return (
      <View className={clsx("max-w-[560px] w-fit py-[20px] px-[24px] rounded-[24px] text-[28px] leading-[40px]",
        message.sender === EnumSender.HR
        ? "bg-white !rounded-tl-none text-primary"
        : "bg-[#418BFF] !rounded-tr-none text-white ml-auto"
      )}>
        {message.content}
      </View>
    )
  }
  function renderRequestCard(message: MyChatMsgResult) {
    let icon;
    if (message.cardContent.icon === EnumMyChatCardIcon.简历卡片) {
      icon = require("../images/swap-resume.png")
    } else if (message.cardContent.icon === EnumMyChatCardIcon.微信卡片) {
      icon = require("../images/swap-wechat.png")
    } else if (message.cardContent.icon === EnumMyChatCardIcon.手机卡片) {
      icon = require("../images/swap-mobile.png")
    }
    // @ts-ignore
    if (!icon) return null
    const rejectTypes: Array<EnumMyChatCardAction> = [
      EnumMyChatCardAction.求职者拒绝交换微信,
      EnumMyChatCardAction.求职者拒绝交换联系方式,
      EnumMyChatCardAction.求职者拒绝向HR发送简历
    ]
    return (
      <View className={clsx("p-[32px] rounded-[24px] border-[2px] border-solid w-[558px] bg-linear-180 from-0% to-100% to-white", {
        "border-theme/20 from-[#E9F2FF]": message.cardContent.color === "blue",
        "border-[#00C580]/20 from-[#E6FFE7]": message.cardContent.color === "green",
        "border-[#FD9900]/20 from-[#FFFBE3]": message.cardContent.color === "yellow",
      })}>
        <View className="flex flex-row items-center gap-[24px]">
          <Image src={icon} className="size-[80px] box-border block object-cover" />
          <View className="text-[28px] !leading-[40px] text-primary">
            {message.cardContent.title}
          </View>
        </View>
        {
          !message.executedState
          ? (
            <View className="flex flex-row justify-between items-center mt-[48px]">
              {
                message.cardContent.actions?.map(item => {
                  const isRejectAction = rejectTypes.includes(item)
                  return (
                    <GpTouchableView key={item} onClick={() => handleRequestCard(message, item, isRejectAction ? "reject" : "agreen")}
                     className={clsx("flex flex-row justify-center items-center rounded-[24px] h-[80px] w-[236px] text-[28px] !leading-[40px]",
                      isRejectAction
                      ? "text-third bg-third/10"
                      : {
                        "text-theme bg-theme/10": message.cardContent.color === "blue",
                        "text-[#0DAF7B] bg-[#0DAF7B]/10": message.cardContent.color === "green",
                        "text-[#FD9900] bg-[#FD9900]/10": message.cardContent.color === "yellow",
                      }
                     )}>
                      {isRejectAction ? "拒绝" : "同意"}
                    </GpTouchableView>
                  )
                })
              }
            </View>
          ) : (
            <GpTouchableView className="mt-[48px] flex flex-row justify-center items-center rounded-[24px] h-[80px] text-[28px] !leading-[40px] text-third bg-third/4">
              {message.executedState === EnumChatMsgExecutedState.同意 ? '已同意' : '已拒绝'}
            </GpTouchableView>
          )
        }
      </View>
    )
  }
  function renderTipMessage(message: MyChatMsgResult) {
    return (
      <View className="text-center text-third text-[24px] !leading-[24px]">
        {message.content}
      </View>
    )
  }
  function renderReplyCard(message: MyChatMsgResult) {
    let icon;
    if (message.cardContent.icon === EnumMyChatCardIcon.微信卡片) {
      icon = require("../images/swap-wechat.png")
    } else if (message.cardContent.icon === EnumMyChatCardIcon.手机卡片) {
      icon = require("../images/swap-mobile.png")
    }
    // @ts-ignore
    if (!icon) return null
    return (
      <View className={clsx("p-[32px] rounded-[24px] border-[2px] border-solid w-[558px] bg-linear-180 from-0% from-[#E9F2FF] to-100% to-white mx-auto", {
        "border-[#00C580]/20 from-[#E6FFE7]": message.cardContent.color === "green",
        "border-[#FD9900]/20 from-[#FFFBE3]": message.cardContent.color === "yellow",
      })}>
        <View className="flex flex-row items-center gap-[24px]">
          <Image src={icon} className="size-[80px] box-border block object-cover" />
          <View className="text-[28px] text-primary">
            <View className="!leading-[40px]">{message.cardContent.title}：</View>
            <View className="!leading-[40px]">{message.cardContent.content}</View>
          </View>
        </View>
        {
          message.cardContent.icon === EnumMyChatCardIcon.微信卡片
          ? (
            <GpTouchableView onClick={() => handleCopyText(message.cardContent.content!)} className="mt-[48px] flex flex-row justify-center items-center rounded-[24px] h-[80px] text-[28px] !leading-[40px] text-[#0DAF7B] bg-[#0DAF7B]/10">
              复制微信号
            </GpTouchableView>
          ) : (
            <View className="flex flex-row justify-between items-center mt-[48px]">
              <GpTouchableView onClick={() => handleCallphone(message.cardContent.content!)} className={clsx("flex flex-row justify-center items-center rounded-[24px] h-[80px] w-[236px] text-[28px] !leading-[40px] text-third bg-third/10")}>
                拨号
              </GpTouchableView>
              <GpTouchableView onClick={() => handleCopyText(message.cardContent.content!)} className={clsx("flex flex-row justify-center items-center rounded-[24px] h-[80px] w-[236px] text-[28px] !leading-[40px] text-[#FD9900] bg-[#FD9900]/10")}>
                复制
              </GpTouchableView>
            </View>
          )
        }

      </View>
    )
  }
  function renderResumePreviewCard(message: MyChatMsgResult) {
    const ext = message.cardContent.content?.split(".").pop()
    return (
      <View className="p-[32px] rounded-[24px] border-[2px] border-solid border-theme/20 w-[558px] bg-linear-180 from-0% from-[#E9F2FF] to-100% to-white mx-auto">
        <View className="flex flex-row items-center gap-[24px]">
          <Image src={require("../images/swap-resume.png")} className="size-[80px] box-border block object-cover" />
          <View className="text-[28px] !leading-[40px] text-primary">
            {message.cardContent.title}.{ext}
          </View>
        </View>
        <GpTouchableView onClick={() =>previewResume(message.cardContent.content!)} className="mt-[48px] flex flex-row justify-center items-center rounded-[24px] h-[80px] text-[28px] !leading-[40px] text-theme bg-theme/10">
          点击预览附件简历
        </GpTouchableView>
      </View>
    )
  }
  function renderInterviewInvite(message: MyChatMsgResult) {
    const actions: Array<React.ReactNode> = []
    const viewNode = (
      <GpTouchableView className="flex flex-1 justify-center items-center h-[80px] rounded-[24px] text-[28px] text-third bg-third/10" onClick={() => {
        navigate(pageMapper.chat.interview, {id: message.interviewId, messageId: message.id}, "navigateTo", {
          events: {
            action(info: {type: "reject" | "agreen"; messageId: number; nextMessageId: number; chatId: number;}) {
              process.env.NODE_ENV !== "production" && console.log("info", info)
              getNextMessage(info.nextMessageId)
            },
          }
        })
      }}>
        查看详情
      </GpTouchableView>
    )
    if (isSetValue(message.executedState)) {
      const map = new Map([
        [EnumChatMsgExecutedState.取消, "已取消"],
        [EnumChatMsgExecutedState.拒绝, "已拒绝"],
        [EnumChatMsgExecutedState.同意, "已接受"],
      ])
      actions.push(
        <GpTouchableView className="flex flex-1 justify-center items-center h-[80px] rounded-[24px] text-[28px] text-third bg-third/4">
          {map.get(message.executedState)}
        </GpTouchableView>
      )
      if (message.executedState === EnumChatMsgExecutedState.同意
        && message.cardContent?.actions?.includes(EnumMyChatCardAction.求职者查看面试详情))
        actions.unshift(viewNode)
    } else {
      message.cardContent?.actions?.forEach(action => {
        if (action === EnumMyChatCardAction.求职者查看面试详情) {
          actions.push(viewNode)
        } else if (action === EnumMyChatCardAction.求职者同意面试邀请) {
          actions.push(
            <GpTouchableView className="flex flex-1 justify-center items-center h-[80px] rounded-[24px] text-[28px] text-theme bg-theme/10" onClick={() => {
              handleInterviewInvite(message, action)
            }}>
              接受面试
            </GpTouchableView>
          )
        }
      })
    }
    return (
      <View className="w-[558px] p-[32px] border-[2px] border-solid border-theme/20 rounded-[24px] bg-linear-180 from-0% from-[#E9F2FF] to-100% to-white">
        <View className="flex flex-row gap-[16px] items-center">
          <GpFontIcon name={message.cardContent?.address ? "icon-ic_xianchangmianshi": "icon-ic_xianshangmianshi"} size={28} className="text-theme" />
          <View className="font-bold text-[30px] !leading-[30px] text-theme">{message.cardContent?.title}</View>
        </View>
        <View className="flex flex-row gap-[16px] items-center mt-[32px]">
          <GpFontIcon name="icon-ic_gangwei" size={28} className="text-placeholder" />
          <View className="text-[28px] !leading-[28px] text-primary">{message.cardContent?.jobName}</View>
        </View>
        <View className="flex flex-row gap-[16px] items-center mt-[32px]">
          <GpFontIcon name="icon-ic_shijian" size={28} className="text-placeholder" />
          <View className="text-[28px] !leading-[28px] text-primary">{message.cardContent?.time}</View>
        </View>
        <View className="flex flex-row gap-[16px] items-center mt-[32px]">
          <GpFontIcon name={message.cardContent?.address ? "icon-gongsidizhidingwei" : "icon-ic_mianshifangshi"} size={28} className="text-placeholder" />
          <View className="text-[28px] !leading-[28px] text-primary">{message.cardContent?.address ?? message.cardContent?.platform}</View>
        </View>
        <View className="flex flex-row items-center gap-[22px] mt-[48px]">
          {actions}
        </View>
      </View>
    )
  }
  function renderInterviewInviteTip(message: MyChatMsgResult) {
    return (
      <View className="max-w-[560px] w-fit py-[20px] px-[24px] rounded-[24px] text-[28px] leading-[40px] bg-[#418BFF] !rounded-tr-none text-white ml-auto">
        {message.content}
        <GpFontIcon name={message.type === EnumChatMessageType.求职者同意面试邀请 ? "icon-xuanzhong" : "icon-ic_jujue"} size={28} className="pl-[16px]" />
      </View>
    )
  }
  function renderLeftExtra() {
    return (
      <View className="flex flex-row items-center gap-[16px]">
        <Image src={chatDetail?.userAvatar ?? __DEF_AVATAR__} className="rounded-[50%] size-[64px] object-cover" />
        <View className="flex flex-col gap-[8px] justify-center w-[356px]">
          <Text className="text-[#393939] text-[28px] leading-[28px] font-bold">{chatDetail?.userName}</Text>
          <Text className="text-[24px] leading-[24px] text-third truncate">{chatDetail?.companyName}</Text>
        </View>
      </View>
    )
  }
  function renderPopups() {
    return (
      <View>
        {renderConfirmPopup(chatDetail)}
      </View>
    )
  }
  return (
    <GpContainer className="bg-[#F4F6FC]" safeArea={false}>
      <GpNavbar
        navigationBarTitleText={null}
        renderLeftExtra={renderLeftExtra}
        onLayout={({statusBarHeight, navigationHeight}) => setNavigationHeight(statusBarHeight + navigationHeight)}
      />
      <View className="flex flex-col overflow-hidden" style={{
        height: `calc(100vh - ${navigationHeight}px)`
      }}>
        <View className="flex flex-row items-center justify-center gap-[108px] box-border bg-white h-[124px] flex-none">
          {
            actionOptions.map(item => (
              <GpTouchableView key={item.value} className="flex flex-col gap-[12px] justify-center items-center" onClick={() => handleAction(item)}>
                <Image src={item.icon} className="size-[40px]" />
                <Text className="text-[24px] leading-[24px]">{item.label}</Text>
              </GpTouchableView>
            ))
          }
        </View>
        <View className="flex-none flex flex-row items-center gap-[16px] border-t border-solid border-t-[#EEEEEE] px-[32px] py-[22px] bg-white box-content">
          <Image src={require('../images/notice.png')} className="size-[80px] object-cover flex-none" />
          <View className="flex-1 w-0 box-border">
            <View className="text-primary text-[28px] !leading-[28px]">开启消息提醒</View>
            <View className="text-third text-[24px] !leading-[24px] mt-[12px]">HR回复消息时无法通知你，建议开启</View>
          </View>
          <GpTouchableView className="text-[24px] text-white px-[20px] h-[48px] !leading-[48px] bg-theme rounded-[32px]">
            开启提醒
          </GpTouchableView>
        </View>
        {renderChat()}
        <View className="flex-none box-border bg-white shadow-[0_-12px_20px_rgba(73,110,169,0.06)]">
          <View className="flex flex-row items-center px-[32px] gap-[16px] h-[120px]">
            <View className="flex-1 h-[80px] rounded-[24px] bg-[#F4F6FC]">
              <Input
                placeholder="和TA聊一聊吧~"
                className="size-full text-primary text-[28px] leading-[80px] px-[24px]"
                placeholderClass="text-third"
                value={input}
                onInput={({detail: {value}}) => setInput(value)}
                onConfirm={handleSend}
              />
            </View>
            <GpTouchableView className="box-border size-fit flex-none" onClick={handleSend}>
              <Image src="/static/images/chat/send.png" className="size-[80px] object-cover"/>
            </GpTouchableView>
          </View>
          <SafeArea position="bottom" />
        </View>
      </View>
      {renderPopups()}
    </GpContainer>
  )
}
